/**
 * 核心模块 JS
 * @authors zhuhui (zhuhui@yidian-mall.com)
 * @date    2019-05-07 14:57:40
 * @version $Id$
 */
$(function(){
    var Objs = {
        load:function(){
            Objs.validRules.render();
            Objs.Captcha.render($('.captcha'));
            Objs.TN.render();
            Objs.sideMenu();
            Objs.comboFile.render();
            Objs.thumbFile.render();
            Objs.echarts.render();
            Objs.loadResize();
            Objs.zTree.render();
        },
        loadResize:function(){
            Objs.Scrollbar.autoRender();
        },
        jQ:function(str){
            if (str !== undefined && str !== '' && typeof(str) !== 'string') {
                return str;
            }
            if (parent !== null && window.frames.length != parent.frames.length){
                return (str === undefined || str === '')?$(window.parent.document):$(window.parent.document).find(str);
            }else{
                return (str === undefined || str === '')?$(document):$('html').find(str);
            }
        },
        createXmlHttpRequest:function (){
            if(window.ActiveXObject){ //如果是IE浏览器
                return new ActiveXObject("Microsoft.XMLHTTP");
            }else if(window.XMLHttpRequest){ //非IE浏览器
                return new XMLHttpRequest();
            }
        },
        TN:{
            ts:'#tabs-box',
            tsItem:'#tabs-box .tab-nav',
            tsDef:'#tabs-box .tab-default',
            tsList:'#tabs-box #tabs-list',
            tsListItem:'#tabs-box #tabs-list .tab-nav',
            tsDel:'#tabs-box #tabs-list .tab-close',
            tsCls:'fa fa-close ',
            tsBody:'#tabContent-box',
            tsBodyItem:'#tabContent-box .tabContent',
            scrollbarOpts:{scrollInertia:0,axis:"x",autoHideScrollbar:true},
            defTarget:'',
            render:function(){
                Objs.TN.defTarget = Objs.jQ(Objs.TN.tsDef).attr('ttarget');
                Objs.jQ(Objs.TN.tsItem).unbind('click').bind('click',function(e){
                    window.event?window.event.cancelBubble = true:e.stopPropagation();
                    if(!e.isPropagationStopped()){
                        Objs.TN.swatch($(this).attr('ttarget'));
                    }
                    e.stopPropagation();
                    return false;
                });
                Objs.TN.rightCMenu.render();
                Objs.jQ(Objs.TN.tsDel).unbind('click').bind('click',function(e){
                    window.event?window.event.cancelBubble = true:e.stopPropagation();
                    if(!e.isPropagationStopped()){
                        Objs.TN.close("ttarget:'"+$(this).parents('.tab-nav').attr('ttarget')+"'");
                    }
                    e.stopPropagation();
                    return false;
                });
                Objs.jQ('.tab-refresh').unbind('click').bind('click',Objs.TN.refresh);
            },
            scrollTo:function(ttarget){
                if (Objs.TN.defTarget === ttarget){
                    return false;
                }
                if (!Objs.utils.isEmptyObj(parent,'frames') && window.frames.length != parent.frames.length){
                　　 window.parent.$.TN.scrollTo(ttarget);
                    return false;
                }
                var cur = Objs.jQ(Objs.TN.tsListItem).index(Objs.jQ(Objs.TN.tsListItem+'[ttarget='+ttarget+']'));
                try{
                    Objs.jQ(Objs.TN.tsList).mCustomScrollbar('scrollTo',Objs.jQ(Objs.TN.tsListItem+":eq("+cur+")"));
                }catch(e){
                    console.error(e.name + ": " + e.message);
                }
            },
            swatch:function(ttarget){
                if (!Objs.utils.isEmptyObj(parent,'frames') && window.frames.length != parent.frames.length){
                　　 window.parent.$.TN.swatch(ttarget);
                    return false;
                }
                var flag ='[ttarget='+ttarget+']';
                if (Objs.jQ(Objs.TN.tsBodyItem+flag).length ===0){
                    Objs.msger.show('warning','标签页面走丢了,自动删除导航标签',1200,{
                        onHidden:function(){
                            Objs.TN.close("ttarget:'"+ttarget+"'");
                        }
                    });
                }else{
                    // 标签页的切换 还包括标签页内容的切换
                    Objs.jQ(Objs.TN.tsItem+','+Objs.TN.tsBodyItem).each(function(index, el){
                        $(el).removeClass('active');
                    });
                    Objs.jQ(Objs.TN.tsItem+flag).addClass('active');
                    var time = new Date().getTime()/1000;
                    Objs.jQ(Objs.TN.tsItem+flag).attr('t', time);
                    Objs.jQ(Objs.TN.tsBodyItem+flag).addClass('active');
                    var refresh = Objs.jQ('.tab-refresh');
                    if (Objs.jQ(Objs.TN.tsBodyItem+flag).find('.loading').length == 0){
                        Objs.TN.load.stop(refresh);
                    }else{
                        Objs.TN.load.continue(refresh);
                    }
                }
                Objs.TN.scrollTo(ttarget);
            },
            close:function(arg){
                if (!Objs.utils.isEmptyObj(parent,'frames') && window.frames.length != parent.frames.length){
                    window.parent.$.TN.close(arg);
                    return false;
                }
                var json = Objs.utils.options(arg);
                if (Objs.utils.isEmptyObj(json)
                    || Objs.utils.isEmptyObj(json.ttarget)){
                    console.warn('data-option is wrong');
                    return false;
                }
                if (Objs.utils.isEmptyObj(json.close)){
                    json.close = 'current';
                }

                var ttar = json.ttarget,max=-1,s_t=Objs.TN.defTarget;
                if (json.close == 'current'){
                    // 标签页的删除 还包括标签页内容的删除
                    var o = Objs.jQ(Objs.TN.tsListItem+'[ttarget='+ttar+']');
                    if (o.hasClass('active')){
                        o.remove();
                        Objs.jQ(Objs.TN.tsItem).each(function(index, el){
                            var cur = parseFloat($(el).attr('t') === undefined?0:$(el).attr('t'));
                            if (cur > max){
                                max = cur;
                                s_t = $(el).attr('ttarget');
                            }
                        });
                        Objs.TN.swatch(s_t);
                    }else{
                        o.remove();
                    }
                    Objs.jQ(Objs.TN.tsBodyItem+'[ttarget='+ttar+']').remove();
                }else{
                    Objs.jQ(Objs.TN.tsListItem).each(function(index, el){
                        var temp = $(el).attr('ttarget');
                        if (json.close == 'all' || json.close == 'other' && ttar !== temp){
                            $(el).remove();
                            Objs.jQ(Objs.TN.tsBodyItem+'[ttarget='+temp+']').remove();
                        }
                    });

                    if (json.close == 'all'){
                        Objs.TN.swatch(s_t);
                        Objs.Scrollbar.operate(Objs.jQ(Objs.TN.tsList),'destroy');
                    }else{
                        Objs.TN.swatch(ttar);
                    }
                }
                Objs.TN.load.stop(Objs.jQ('.tab-refresh'));
            },
            open:function(arg){
                var time = new Date().getTime()/1000,curo = Objs.jQ(Objs.TN.tsListItem+'.active');
                if (curo.length > 0 && time - parseInt(curo.attr('t')) < 1){
                    Objs.msger.show('info','您操作的太快了，我都跟不上节奏了',800);
                    return false;
                }
                if (window.frames.length != parent.frames.length){
                　　  window.parent.$.TN.open(arg);
                    return false;
                }

                var json = Objs.utils.options(arg);
                if (Objs.utils.isEmptyObj(json)
                    || Objs.utils.isEmptyObj(json.url)
                    || Objs.utils.isEmptyObj(json.ttarget) || Objs.utils.isEmptyObj(json.title)){
                    console.warn('data-option is wrong');
                    return false;
                }
                var list = [];
                Objs.jQ(Objs.TN.tsItem+'[ttarget]').each(function(index, el){
                    list.push($(el).attr('ttarget'));
                });
                if (Objs.utils.isEmptyObj(json.ttype)){
                    json.ttype = 'iframe';
                }
                if (json.ttype === 'request'){
                    window.location.href = json.url;
                    return false;
                }
                if (json.replaceLoad === undefined) {
                    json.replaceLoad = false;
                }
                // TODO 是否需要将destroy改成update？
                Objs.Scrollbar.operate(Objs.jQ(Objs.TN.tsList),'destroy');

                var flag = 'ttarget="'+json.ttarget+'"';
                if (list.indexOf(json.ttarget) == -1){// 校验是否存在,这是不存在
                    // 定义并初始化
                    var _h = '<div class="tab-nav" '+flag+' t="'+time+'"><span>'+json.title+'</span><i class="tab-close icon-small '+Objs.TN.tsCls+'"></i></div>';
                    if (Objs.jQ(Objs.TN.tsList).find('.mCSB_container').length > 0){
                        Objs.jQ(Objs.TN.tsList).find('.mCSB_container').append(_h);
                    }else{
                        Objs.jQ(Objs.TN.tsList).append(_h);
                    }
                    _h = '';// 重新初始化
                    _h += '<div class="tabContent" '+flag+'>';
                    if (json.ttype === 'iframe'){
                        _h += '<iframe class="load-page" src="'+json.url+'" ttype="'+json.ttype+'" frameborder="0" width="100%" height="100%"></iframe>';
                    }else{
                        _h += '<div class="load-page" src="'+json.url+'" ttype="'+json.ttype+'"></div>';
                    }
                    _h += '</div>';
                    Objs.jQ(Objs.TN.tsBody).append(_h);
                    Objs.TN.render();

                    var c = Objs.jQ(Objs.TN.tsBodyItem+'['+flag+']'),refresh = Objs.jQ('.tab-refresh');
                    Objs.TN.load.render(c,refresh);
                    Objs.TN.load.clear(c,refresh);
                }else{
                    if (json.replaceLoad) {
                        var c = Objs.jQ(Objs.TN.tsBodyItem+'['+flag+']'),refresh = Objs.jQ('.tab-refresh');
                        c.children('.load-page').attr('src', json.url).ready();
                        Objs.TN.load.render(c,refresh);
                        Objs.TN.load.clear(c,refresh);
                    }
                }
                Objs.Scrollbar.render(Objs.jQ(Objs.TN.tsList),Objs.TN.scrollbarOpts);

                Objs.TN.swatch(json.ttarget);
            },
            load:{
                close:'fa fa-close ',
                loading:'fa fa-spinner ',
                loop:'fa-spin',
                render:function(c,refresh){
                    Objs.TN.load.continue(refresh);
                    if (c.find('.loading').length == 0){
                        var _html = '';
                        _html +='<div class="loading"><div class="load-layer"><div class="load-txt">';
                        _html +='<i class="'+Objs.TN.load.loading+Objs.TN.load.loop+'"></i>正在处理，请稍等. . . ';
                        _html +='<div class="load-stop" title="停止加载"><i class="'+Objs.TN.load.close+'"></i></div>';
                        _html +='</div></div></div>';
                        c.children('.load-page').before(_html);
                    }
                    c.find('.loading .load-stop').unbind('click').bind('click',function(event){
                        window.event?window.event.cancelBubble = true:event.stopPropagation();
                        if(!event.isPropagationStopped()){
                            Objs.TN.load.stop(refresh);
                            c.find('.loading').remove();
                        }
                        event.stopPropagation();
                        return false;
                    });
                    Objs.TN.load.loadPage(c,refresh,c.children('.load-page').attr('ttype'));
                },
                clear:function(c,refresh){
                    c.children('.load-page').on("load",function(){
                        if (c.children('.loading').length > 0){
                            c.children('.loading').remove();
                        }
                        Objs.TN.load.stop(refresh);
                    });
                },
                stop:function(refresh){
                    if (refresh.children('i').hasClass(Objs.TN.load.loop)){
                        refresh.children('i').removeClass(Objs.TN.load.loop);
                    }
                    refresh.removeClass('disabled').unbind('click').bind('click',Objs.TN.refresh);
                },
                continue:function(refresh){
                    if (!refresh.children('i').hasClass(Objs.TN.load.loop)){
                        refresh.children('i').addClass(Objs.TN.load.loop);
                    }
                    refresh.addClass('disabled').unbind('click');
                },
                loadPage:function(c,refresh,_ttype){
                    var _src = c.children('.load-page').attr('src'),
                        _ttarget = c.attr('ttarget');
                    if (_ttype !== 'iframe'){
                        $.post(_src, {ttype:_ttype},function(data, textStatus, xhr){
                            if (c.children('.loading').length > 0){
                                c.children('.loading').remove();
                            }
                            Objs.TN.load.stop(refresh);
                            if (textStatus == 'success'){
                                if (data.status == undefined){
                                    c.children('.load-page').empty().append(data);
                                }else{
                                    Objs.msger.show('warning',data.message,1000,{
                                        onHidden:function(){
                                            Objs.TN.close("ttarget:'"+_ttarget+"'");
                                        }
                                    });
                                }
                            }else{
                                Objs.msger.show('warning','操作失败，请联系管理员',1000,{
                                    onHidden:function(){
                                        Objs.TN.close("ttarget:'"+_ttarget+"'");
                                    }
                                });
                            }
                        });
                    }
                },
            },
            refresh:function(){
                var refresh = Objs.jQ('.tab-refresh');
                if (!refresh.hasClass('disabled')){
                    var c = Objs.jQ(Objs.TN.tsBodyItem+'.active'),
                        _ttype = c.children('.load-page').attr('ttype');
                    if (c.children('.load-page').length > 0){
                        Objs.TN.load.render(c,refresh);
                        if (_ttype !== 'iframe'){
                            Objs.TN.load.loadPage(c,refresh,_ttype);
                        }else{
                            c.children('.load-page').attr('src', c.children('.load-page').attr('src')).ready();
                            Objs.TN.load.clear(c,refresh);
                        }
                    }else{
                        Objs.msger.show('warning','标签页面不存在',1000);
                    }
                }else{
                    console.warn('当前导航标签页正在加载中....');
                }
            },
            rightCMenu:{
                _default:{
                    redirect:{display:true,vals:[],title:'切换指定页'},
                    current:{display:true,val:'',title:'关闭当前'},
                    other:{display:true,val:'',title:'关闭其他'},
                    all:{display:true,val:'',title:'关闭所有'},
                },
                render:function(){
                    if(Objs.jQ(Objs.TN.ts).length > 0 && Objs.jQ('#rightContextMenu').length === 0){
                        var _def = Objs.TN.rightCMenu._default,_html_temp = '';
                        _html_temp = '<div id="rightContextMenu" style="display:none"><div class="rightContextBox">';
                        for(var t in Objs.TN.rightCMenu._default){
                            if (_def[t].vals === undefined){
                                _html_temp += '<div class="item-menu" data="'+t+'" ttarget="'+_def[t].val+'"><span>'+_def[t].title+'</span></div>';
                            }else{
                                _html_temp += '<div class="item-menu" id="contextMenu-'+t+'"><span>'+_def[t].title+'</span>';
                                _html_temp += '<div class="list scrollbar" data-options="scrollInertia:0,axis:\'y\',autoHideScrollbar:true">';
                                _html_temp += '<div class="rightContextList"></div>'
                                _html_temp += '</div></div>';
                            }
                        }
                        _html_temp += '</div></div>';
                        Objs.jQ().find('html>body').append(_html_temp);
                    }
                    Objs.jQ(Objs.TN.tsItem).unbind('contextmenu').bind("contextmenu",function(e){
                        window.event?window.event.cancelBubble = true:e.stopPropagation();
                        if(!e.isPropagationStopped()){
                            var elem = Objs.jQ('#rightContextMenu'),
                                current_tab = 'tab-home';
                                if (!$(this).hasClass('tab-default')){
                                    current_tab = $(this).attr('ttarget');
                                }
                                var _style = {},_def = Objs.TN.rightCMenu._data(Objs.TN.rightCMenu._default,current_tab),
                                _html = '';
                            if(elem.length > 0){

                                _style = {top:(e.pageY-1)+'px',left:(e.pageX-1)+'px'};
                                var redirects = _def.redirect.vals;
                                for (var i = 0; i < redirects.length; i++){
                                    _html += '<div class="item-menu" data="redirect" ttarget="'+redirects[i].val+'" title="'+redirects[i].title+'">'+redirects[i].title+'</div>';
                                }

                                elem.find('.rightContextList').empty().append(_html);
                                for (var d in _def){
                                    var itm = elem.find('.item-menu[data='+d+']');
                                    itm.attr('ttarget', _def[d].val);
                                    if (_def[d].display){
                                        itm.show();
                                    }else{
                                        itm.hide();
                                    }
                                }
                                if (_def.redirect.display || _def.current.display || _def.other.display || _def.all.display){
                                    elem.css(_style).show();
                                }

                                elem.mouseleave(function(){
                                    $(this).removeAttr('style').hide();
                                }).find('.item-menu[data]').unbind('click').bind('click',function(event){
                                    var _this = $(this),
                                        t = _this.attr('data'),
                                        ttargets = _this.attr('ttarget');
                                    if (t === 'current' || t === 'other' || t === 'all'){
                                        Objs.TN.close("ttarget:'"+ttargets+"',close:'"+t+"'");
                                    }else{
                                        Objs.TN.swatch(ttargets);
                                    }
                                    _this.parents('#rightContextMenu').removeAttr('style').hide();
                                }).end();
                            }
                        }
                        e.stopPropagation();
                        return false;
                    });
                },
                _data:function(data,arg){
                    data.redirect.vals = [];
                    data.current.val = data.other.val = arg;
                    data.redirect.display = data.current.display = data.other.display = data.all.display = true;
                    Objs.jQ(Objs.TN.tsItem).each(function(index, el){
                        data.redirect.vals.push({val:$(el).attr('ttarget'),title:$(el).find('span').text()});
                    });
                    if (data.current.val === 'tab-home'){
                        data.other.display = false;
                        data.current.display = false;
                    }
                    if (data.redirect.vals.length < 2){
                        data.redirect.display = false;
                        data.all.display = false;
                    }
                    return data;
                },
            },
        },
        sideMenu:function(){
            $('.menu-item').unbind('click').bind('click',function(event){
                window.event?window.event.cancelBubble = true:event.stopPropagation();
                if(!event.isPropagationStopped()){
                    var _this = $(this),child = _this.children('.menu-list');
                    _this.siblings().removeClass('active').find('a').removeClass('current')
                        .end().find('.menu-item').removeClass('active')
                        .end().find('.menu-list').hide('fast');
                    if (!_this.hasClass('active')){
                        _this.addClass('active').children('.menu-list').show('fast');
                        if (child.length === 0){
                            _this.children('a').addClass('current');
                        };
                    }else{
                        _this.removeClass('active').children('.menu-list').hide('fast');
                        if (child.length === 0){
                            _this.children('a').removeClass('current');
                        };
                    }
                }
                event.stopPropagation();
                return false;
            });
            $('#menu-btn').unbind('click').bind('click',function(event){
                // 防止冒泡
                window.event?window.event.cancelBubble = true:event.stopPropagation();
                if(!event.isPropagationStopped()){//确定stopPropagation是否被调用过
                    var _body = $('body');
                    if (!_body.hasClass('ZHjui')){
                        _body.addClass('ZHjui');
                    }
                    if($('#leftSide-layout').offset().left < 0 || _body.hasClass('freeze')){
                        _body.removeClass('freeze').addClass('active');
                    }else{
                        _body.addClass('freeze').removeClass('active');
                    };
                }
                //必须要，不然e.isPropagationStopped()无法判断stopPropagation是否调用过
                event.stopPropagation();
                return false;
            });
        },
        Scrollbar:{
            autoRender:function(){
                $('.scrollbar').each(function(index, el){
                    Objs.Scrollbar.render($(el));
                });
            },
            render:function(element,opts){
                var option = {},H = element.outerHeight(true),W = element.outerWidth(true);
                if (Objs.utils.isEmptyObj(opts)){
                    var opts = Objs.utils.options(element);
                }
                if (!Objs.utils.isEmptyObj(opts.H)){
                    H -= parseInt(opts.H);
                    element.outerHeight(H);
                }
                if (!Objs.utils.isEmptyObj(opts.W)){
                    W -= parseInt(opts.W);
                    element.outerWidth(W);
                }
                if (!Objs.utils.isEmptyObj(opts.auto) && Boolean(opts.auto) === true){
                    element.find('.scrollbar-body').height(H);
                }
                $.map(["setWidth","setHeight","axis","scrollInertia","scrollbarPosition","autoDraggerLength","alwaysShowScrollbar"],function(p){
                    if (!Objs.utils.isEmptyObj(opts[p])){
                        option[p] = opts[p];
                    }
                });

                try{
                    element.mCustomScrollbar(option);
                }catch(e){
                    console.warn(e.name + ": " + e);
                }
            },
            operate:function(element,type){
                if (typeof(type) != 'undefined' && (type == 'destroy' || type == 'update')){
                    try{
                        element.mCustomScrollbar(type);
                        if (type == 'destroy'){
                            element.removeAttr('style').removeClass('mCS_destroyed');
                        }
                    }catch(e){
                        console.warn(e.name + ": " + e.message);
                    }
                }
            }
        },
        Captcha:{
            render:function(ele){
                Objs.Captcha.bind(ele);
                Objs.Captcha.setTime(Objs.jQ(ele),Objs.jQ(ele).attr('value'));
            },
            bind:function(ele) {
                Objs.jQ(ele).unbind('click').bind('click',function(){
                    var _this = $(this),
                        validatebox = [],
                        opts = Objs.utils.options(_this);
                    opts.countdown = Objs.utils.isEmptyObj(opts.countdown)?11110:opts.countdown;
                    if (!Objs.utils.isEmptyObj(opts.verify)){
                        if (Objs.utils.isEmptyObj(opts.id)){
                            opts.id = '.captchaValid';
                        }
                        opts.validText = 'example';
                        validatebox = _this.parents('form').find('input'+opts.id);
                        if (validatebox.length !== 1){
                            console.warn('Captcha validate input is not found');
                            return false;
                        };
                        opts.validText = validatebox.val();
                        if (!Objs.validRules.rules[opts.verify].validator(opts.validText)){
                            Objs.msger.show('error',Objs.validRules.rules[opts.verify].message);
                            return false;
                        }
                    }
                    if (!Objs.utils.isEmptyObj(opts.url)){
                        var url = opts.url;
                        delete opts.id;
                        delete opts.url;
                        Objs.requestAjax({url:url,data:opts},function(res){
                            if (!res instanceof Object){
                                res = eval('(' + res + ')');
                            }
                            if (res.status !== undefined){
                                res.message = (res.message !== undefined && res.message !== '')?res.message:'message参数不存在';
                                if ($.inArray(res.status, [1,'1',true,'true']) >= 0) {
                                    Objs.Captcha.setTime(_this,parseInt(opts.countdown,2));
                                    Objs.msger.show($.inArray(res.status, [1,'1',true,'true']) >= 0?'success':'warning',res.message);
                                }else{
                                    Objs.msger.alert('error',res.message);
                                }
                            }
                        });
                    }else{
                        console.warn('Send Captcha URL is wrong');
                    }
                });
            },
            setTime:function(ele,count){
                count = !count?0:count;
                count = parseInt(count);
                if (count == 0){
                    ele.removeClass("disabled");
                    ele.html("获取验证码");
                    ele.unbind('click').bind('click',Objs.Captcha.bind(ele));
                } else {
                    Objs.Captcha.runTime(ele,count);
                }
            },
            runTime:function(ele,count){
                ele.addClass("disabled");
                ele.html("重新发送(" + count + ")");
                count--;
                ele.unbind('click');
                setTimeout(function(){
                    Objs.Captcha.setTime(ele,count);
                },1000);
            },
        },
        validRules:{
            rules:{
                email:{
                    validator:function(value,param){
                        var reg = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
                        return reg.test(value);
                    },
                    message:'不是有效的邮箱地址',
                },
                url:{
                    validator:function(value,param){
                        var reg = /^((ht|f)tps?):\/\/([\w-]+(\.[\w-]+)*\/?)+(\?([\w\-\.,@?^=%&:\/~\+#]*)+)?$/;
                        return reg.test(value)
                    },
                    message:'不是有效的URL地址',
                },
                equals:{
                    validator:function(value,param){
                        return value == $(param[0]).val();
                    },
                    message:'输入的内容不一致,请重新输入',
                },
                minLength:{
                    validator:function(value, param){
                        return value.length >= param[0];
                    },
                    message:'请最少输入 {0} 个字符',
                },
                maxLength:{
                    validator:function(value, param){
                        return value.length <= param[0];
                    },
                    message:'请最多输入 {0} 个字符',
                },
                mustLength:{
                    validator:function(value, param){
                        return value.length == param[0];
                    },
                    message:'请输入 {0} 个字符',
                },
                phone:{
                    validator:function(value, param){
                        var reg = /^1(3|4|5|7|8)\d{9}$/;
                        return reg.test(value);
                    },
                    message:'请输入有效的手机号',
                },
                password:{
                    validator:function(value, param){
                        var reg = /^(?=.*?[a-zA-Z])(?=.*?\d).{8,16}$/;
                        return reg.test(value);
                    },
                    message:'请输入8~16位的大小写字母、数字组合',
                },
                numberLength:{
                    validator:function(value, param){
                        var reg = new RegExp("^\\d{"+param[0]+"}$");
                        return reg.test(value);
                    },
                    message:'请输入{0}位数值',
                },
                number:{
                    validator:function(value, param){
                        var reg = new RegExp("^[0-9]+$");
                        return reg.test(value);
                    },
                    message:'只能输入数字',
                },
                fileSize:{
                    validator:function(value, param){
                        var size = param[0],unit = param[1],vfileSize = Objs.utils.fileSize(size,unit);
                        if (vfileSize.formula === 0){
                            return false;
                        }
                        var fileInp;
                        if ($(this).next('input[type=file]').length === 0){
                            fileInp = $(this).next('span.textbox.filebox').find('input[type=file]');
                        }else{
                            fileInp = $(this).next('input[type=file]');
                        }
                        if (fileInp.length > 0){
                            var files = fileInp[0].files;
                            for(var i=0;i < files.length;i++){
                                if (files[i].size < parseFloat(size) * vfileSize.formula){
                                    continue;
                                }else{
                                    return false;
                                }
                            }
                        };
                        return true;
                    },
                    message:'文件大小必须小于 {0}{1}',
                },
            },
            render:function(){
                if ($.fn.validatebox){
                    $.extend($.fn.validatebox.defaults.rules, Objs.validRules.rules);
                }
            },
        },
        msger:{
            title:'操作提示',
            mtitle:'消息提示',
            loadText:'小弟正在飞速加载. . .&nbsp;&nbsp;{value}%',
            shows:function(Msg){
                var n = 1;
                for (var k in Msg){
                    for (var i = 0; i < Msg[k].length; i++){
                        this.show(k,Msg[k][i],n*5000);
                        n++;
                    }
                    delete Msg[k];
                }
            },
            show:function(type,content,time,callback){
                if (time instanceof Object){
                    callback = time;
                    time = 1200;
                }else{
                    time = parseInt(time);
                    time = time > 0?time:1200;
                }
                type = ((type === undefined || type == '')?'info':type);
                if (content !== undefined && content != ''){
                    var options = {timeOut:time,extendedTimeOut:time};
                    Object.assign(options,callback);
                    // options.onShown =function(){ console.log('消息展示的回调'); }
                    // options.onHidden =function(){ console.log('消息隐藏的回调'); }
                    // options.onclick =function(){ console.log('点击消息的回调'); }
                    // options.onCloseClick =function(){ console.log('点击关闭按钮的回调'); }
                    var toastr = Objs.toastr(options);
                    toastr.notify({type:type,message:content,title:this.mtitle});
                }
            },
            clear:function(){
                var toastr = Objs.toastr({});
                toastr.clear();
            },
            easyShow:function(message){
                $.messager.show({
                    title:this.title,
                    msg:message,
                    timeout:800,
                    showType:'slide',
                });
            },
            confirm:function(message,callback){
                $.messager.confirm(this.title,message,callback);
            },
            alert:function(type,message,callback){
                // type:info error question warning progress
                $.messager.alert(this.title,message,type,callback);
            },
            progress:function(open,t){
                if (open){
                    return win = $.messager.progress({
                        text:this.loadText,
                        interval:t===undefined?300:t,
                    });
                }else{
                    $.messager.progress('close');
                    return false;
                }
            },
            prompt:function(message,callback){
                $.messager.prompt(this.title,message,callback);
            }
        },
        grid:{
            getRows:function(opt){
                var rows = [];
                if (opt.type == 'datagrid'){
                    rows = $(opt.id).datagrid('getChecked');
                }else if (opt.type == 'treegrid'){
                    rows = $(opt.id).treegrid('getSelections');
                }
                return rows;
            },
            paramData:function(rows,opt){
                if (opt.chkSelects !== undefined && opt.chkSelects > 0){
                    opt.uncheckMsg = (opt.uncheckMsg == undefined || opt.uncheckMsg == '')?'请先勾选要操作的数据':opt.uncheckMsg;
                    if (rows.length == 0){
                        Objs.msger.alert('warning',opt.uncheckMsg);
                        return false;
                    }
                    if (opt.chkSelects == 1 && rows instanceof Object && rows instanceof Array && rows.length != 1){
                        Objs.msger.alert('warning','请勾选一条要操作的数据');
                        return false;
                    }
                }
                if (opt.params == undefined){
                    return {};
                }
                var res = {},str = opt.params,arr = str.split(',');
                for(var i in arr){
                    var alias = arr[i].split(':'),key,key_val,values;
                    if (alias.length == 2){
                        key = alias[0];
                        key_val = alias[1];
                    }else{
                        key = arr[i];
                        key_val = arr[i];
                    }
                    if (opt.chkSelects == 1){
                        values = (rows instanceof Object && rows instanceof Array)?rows[0][key_val]:rows[key_val];
                    }else{
                        values = rows.map(function(row){return row[key_val];});
                    }

                    res[key] = values;
                }
                return res;
            },
            format:{
                date:function(value,ele) {
                    return dateFormat(value,ele.format);
                },
                status:function(value,ele) {
                    var temp = ele.format.split(";"),status = [];
                    for (var i = 0; i < temp.length; i++) {
                        var t = temp[i].split(":");
                        status[t[0]] = t[1];
                    }
                    return status[value];
                },
                link:function(opts,ele) {
                    var value = opts.value;
                    delete opts.value;
                    var param = opts.param;
                    delete opts.param;
                    if (opts.method === 'openTab') {
                        opts.oTab.url = Objs.utils.urlSetParams(opts.oTab.url,param);
                    }
                    if (opts.method === 'openDialog' && opts.dialog.href !== undefined) {
                        opts.dialog.href = Objs.utils.urlSetParams(opts.dialog.href,param);
                    }
                    if (opts.method === 'doAjax' || opts.method === 'openWindow' || opts.method === 'request') {
                        opts.url = Objs.utils.urlSetParams(opts.url,param);
                    }
                    var str = JSON.stringify(opts).replace(/\"/g,"'");
                    return '<a onclick="$.comboEvn(this)" data-options="'+str+'">'+value+'</a>';
                }
            },
        },
        echarts:{
            defOpts:{
                target:{},
                theme:'light',
                grid:{
                    width:'auto',
                    height:'auto',
                },
                title:{
                    textStyle:{
                        fontSize:'14',
                    }
                },
                toolbox:{
                    show:true,
                    feature:{
                        mark:{show:true},
                        dataView:{show:true, readOnly:false},
                        magicType:{
                            show:true,
                            type:['pie', 'funnel']
                        },
                        restore:{show:true},
                        saveAsImage:{show:true}
                    }
                },
            },
            render:function(){
                $('.zechart').each(function(index, dom){
                    var el = $(dom),opts = Objs.utils.options($(dom));
                    opts = $.extend(true, {}, Objs.echarts.defOpts, opts);
                    var h = el.outerHeight();
                    var defH = $.trim(dom.style['height']||"");
                    if(defH){
                        if(defH.indexOf("%")==-1){
                            defH = parseInt(defH);
                            if(isNaN(defH)){
                                defH = undefined;
                            }
                        }
                        opts.height = defH;
                    }else{
                        opts.height = Math.max(opts.height||0,h);
                    }
                    el.css('height', opts.height);
                    Objs.echarts.remoteCanvas(dom,false);
                });
            },
            remoteCanvas:function(dom,isClick){
                var params = {},formDom = false;
                if (!$(dom).hasClass('zechart')){
                    var wrap = $(dom).parents('.zhwrap'),
                        formDom = wrap.find('form');
                    if (wrap.find('.zechart').length == 1){
                        dom = wrap.find('.zechart')[0];
                    }
                }
                var opts = Objs.utils.options($(dom));
                opts.target = dom;
                opts = $.extend(true, {}, Objs.echarts.defOpts, opts);
                var chart = echarts.init(dom,opts.theme||'light');
                chart.showLoading();
                params.url = opts.url;
                params.success =function(res){
                    this.chart.hideLoading();
                    if (!res instanceof Object){
                        res = eval('(' + res + ')');
                    }
                    if ($.inArray(res.status, [1,'1',true,'true']) >= 0){
                        var topts = $.extend(true, {}, Objs.echarts.defOpts, res.option);
                        topts.contentToOption = function(){
                            Objs.echarts.remoteCanvas(dom,false);
                        }
                        this.chart.setOption(topts);
                    }else{
                        if (this.isClick){
                            $(dom).html(res.message);
                            Objs.msger.show('warning',res.message);
                        }else{
                            console.error('echarts load 0:'+res.message);
                        }
                    }
                };
                if (formDom === false){
                    params.isClick = isClick||true;
                    params.chart = chart;
                    params.error =function(httpRequest){
                        this.chart.hideLoading();
                        if (this.isClick){
                            $(dom).html(httpRequest.status+':'+httpRequest.statusText);
                            Objs.msger.show('warning',httpRequest.status+':'+httpRequest.statusText);
                        }else{
                            console.error('echarts load error:'+httpRequest.status+':'+httpRequest.statusText);
                        }
                    }
                    Objs.requestAjax(params,{});
                }else{
                    formDom[0].isClick = isClick||true;
                    formDom[0].chart = chart;
                    formDom[0].method = "post";
                    params.iframe = true;
                    params.novalidate = true;
                    params.ajax = true;
                    formDom.form('submit',params);
                }
            }
        },
        thumbFile:{
            defOpts:{
                target:{},
                url:'',
                accept:'image/*',
                limit:[1,'MB'],
                imageUrl:'',
                view:false,
                thumbPic:true,
                autoUpload:false,
                wrapper:'zfwrap',
                div:'<div></div>',
                btnCls:'btn-sm btn-outline',
                position:'bottom',
                btns:[],
            },
            render:function(){
                $('.zfilebox').each(function(index, element){
                    var opts = Objs.utils.options($(element));
                    opts.target = element;
                    opts.btns = [
                        {
                            cls:'iconChange btn-primary',
                            title:'浏览',
                            show:true,
                            handler:function(){Objs.thumbFile.change(this);},
                        },{
                            cls:'iconUpload btn-info',
                            title:'上传',
                            show:false,
                            handler:function(){Objs.thumbFile.upload(this);},
                        },{
                            cls:'iconDelete btn-danger',
                            title:'删除',
                            show:false,
                            handler:function(){Objs.thumbFile.delete(this);},
                        },
                    ];
                    Objs.thumbFile.options(opts);
                });
            },
            options:function(opts){
                var box = $(opts.target),
                    zshade = box.find('.zshade').empty(),
                    fInp = box.find('input[type=file]'),
                    ostyle = {width:box.outerWidth(),height:box.outerHeight()};
                opts = $.extend(true, {}, Objs.thumbFile.defOpts, opts);
                box.addClass(opts.wrapper);
                opts.defCss = {};
                $.map(["width","height","minWidth","maxWidth","minHeight","maxHeight"],function(p){
                    var pv = $.trim(opts.target.style[p]||"");
                    if(pv){
                        if(pv.indexOf("%")==-1){
                            pv = parseInt(pv);
                            if(isNaN(pv)){
                                pv = undefined;
                            }
                        }
                        opts.defCss[p] = pv;
                    }
                });
                if (opts.defCss.width){
                    opts.width = opts.defCss.width;
                }
                if (opts.width === undefined){
                    opts.width = 'auto';
                }
                if (opts.width && opts.width != 'auto' && (opts.width.toString()).indexOf("%") == -1){
                    opts.width = Math.max(opts.width||0,ostyle.width);
                }
                opts.width = opts.width?opts.width:ostyle.width;

                if (opts.defCss.height){
                    opts.height = opts.defCss.height;
                }
                if (opts.height && opts.height != 'auto' && (opts.height.toString()).indexOf("%") == -1){
                    opts.height = Math.max(opts.height||0,ostyle.height);
                }
                opts.height = opts.height?opts.height:ostyle.height;
                box.css({width:opts.width,height:opts.height});
                if (!opts.view){
                    if (box.find('.zshade').length === 0){
                        zshade = $(opts.div).addClass('zshade').appendTo(box).empty();
                        if (opts.position == 'bottom') {
                            zshade.css('bottom', '0');
                        }
                        if (opts.position == 'middle') {
                            zshade.css({
                                height: '100%',
                                paddingTop: (box.height()-40)/2,
                            });
                        }
                        if (opts.position == 'top') {
                            zshade.css('top', '0');
                        }
                    }
                    for(var i=0;i<opts.btns.length;i++){
                        var btn = opts.btns[i];
                        var tool = $(opts.div).addClass('btn '+opts.btnCls+' '+btn.cls).html(btn.title).appendTo(zshade);
                        if (!btn.show){
                            tool.hide();
                        }
                        tool[0].onclick=eval(btn.handler||function(){});
                    }
                    if (opts.url === ''){
                        box.find('.iconUpload').remove();
                    }
                }
                if (opts.imageUrl !== ''){
                    box.find('.iconDelete').show();
                    box.find('img').remove();
                    $('<img>').css({height:box.outerHeight()}).appendTo(box).attr('src', opts.imageUrl);
                    var inp = box.find('input[type=hidden]');
                    if (inp.length === 0){
                        inp = $('<input type="hidden">').appendTo(box);
                        inp.attr('name', opts.name?opts.name:'zimg');
                    }
                    inp.val(opts.imageUrl);
                }
            },
            change:function(element){
                var el = $(element),
                    wrapper = el.parents('.zfwrap'),
                    opts = Objs.utils.options(wrapper),
                    fInp = wrapper.find('input[type=file]');
                if (fInp.length === 0){
                    fInp = $('<input type="file">').appendTo(wrapper);
                    fInp.attr('name', opts.name?opts.name:'zimg');
                }
                opts = $.extend(true, {}, Objs.thumbFile.defOpts, opts);
                fInp.attr('accept', opts.accept);
                fInp.click();
                fInp[0].onchange =function(){
                    if (this.files && this.files[0]){
                        if (opts.limit){
                            vfileSize = Objs.utils.fileSize(opts.limit[0],opts.limit[1]);
                            if (vfileSize.formula === 0){
                                Objs.msger.show('warning',vfileSize.message);
                                return false;
                            }
                            if (this.files[0].size > parseFloat(opts.limit[0]) * vfileSize.formula){
                                Objs.msger.show('warning','上传文件不能大于'+opts.limit[0]+opts.limit[1]);
                                return false;
                            };
                        }
                        if (opts.thumbPic === true){
                            var reader = new FileReader();
                            reader.onload =function(e){
                                var img = wrapper.find('img');
                                if (img.length===0){
                                    img = $('<img>').css({width:'auto',height:wrapper.outerHeight()}).appendTo(wrapper);
                                }
                                img.attr('src', e.target.result);
                            }
                            reader.readAsDataURL(this.files[0]);
                            wrapper.find('.iconDelete').show();
                            if (opts.url !== ''){
                                wrapper.find('.iconUpload').show();
                            }
                        }
                        if (opts.autoUpload === true){
                            Objs.thumbFile.upload(element);
                        }
                    }
                }
            },
            upload:function(element){
                var el = $(element),
                    wrapper = el.parents('.zfwrap'),
                    opts = Objs.utils.options(wrapper),
                    fInp = wrapper.find('input[type=file]'),
                    formData = new FormData(),
                    params = {
                        url:opts.url,
                        cache:false,
                        processData:false,
                        contentType:false,
                        data:formData
                    };
                opts = $.extend(true, {}, Objs.thumbFile.defOpts, opts);
                if (fInp.length === 1){
                    if (fInp[0].files && fInp[0].files[0] && opts.url){
                        wrapper.find('.iconChange').hide()
                            .end().find('.iconDelete').hide()
                            .end().find('.iconUpload').hide();
                        formData.append(fInp.attr('name'), fInp[0].files[0]);
                        Objs.msger.progress(true);
                        Objs.requestAjax(params,function (res){
                            if (!res instanceof Object){
                                res = eval('(' + res + ')');
                            }
                            Objs.msger.progress(false);
                            wrapper.find('.iconChange').show()
                                .end().find('.iconDelete').show()
                                .end().find('.iconUpload').hide();
                            res.message = (res.message !== undefined && res.message !== '')?res.message:'message参数不存在';
                            if (res.status !== undefined){
                                var t = 'warning';
                                if ($.inArray(res.status, [1,'1',true,'true']) >= 0){
                                    fInp.val('');
                                    if (opts.thumbPic === true){
                                        wrapper.find('img').attr('src',res.filePath);
                                    }
                                    if (res.filePath){
                                        var inp = wrapper.find('input[type=hidden]');
                                        if (inp.length === 0){
                                            inp = $('<input type="hidden">').appendTo(wrapper);
                                            inp.attr('name', opts.name?opts.name:'zimg');
                                        }
                                        inp.val(res.filePath);
                                    }else{
                                        wrapper.find('input').remove();
                                    }
                                    t = 'success';
                                    Objs.comboCallback(opts,{});
                                }
                                Objs.msger.show(t,res.message);
                                return false;
                            }
                        });
                    }
                }else{
                    Objs.msger.show('warning','请选择要上传文件');
                    return false;
                }
            },
            delete:function(element){
                var el = $(element),
                    wrapper = el.parents('.zfwrap'),
                    opts = Objs.utils.options(wrapper),
                    img = wrapper.find('img');
                opts = $.extend(true, {}, Objs.thumbFile.defOpts, opts);
                wrapper.find('input[type=file]').val('').end().find('.iconUpload').hide();
                if (opts.imageUrl !== ''){
                    if (img.length > 0){
                        var path = '';
                        if (img.attr('src') === opts.imageUrl){
                            img.remove();
                        }else{
                            img.attr('src', opts.imageUrl);
                            path = opts.imageUrl;
                        }
                        wrapper.find('input[type=hidden]').val(path);
                    }
                }else{
                    wrapper.find('input[type=hidden]').val('')
                        .end().find('img').remove();
                }
            },
        },
        comboFile:{
            render:function(){
                $('.fcombogrid').each(function(index, el){
                    var g = $(el),
                        opts = g.combogrid('options'),
                        grid = g.combogrid('grid'),
                        gopts = grid.datagrid('options'),
                        t = 't'+new Date().getTime();
                    g.attr('id', t);
                    opts.id = t;
                    opts.onClickClearIcon =function(arg){
                        $(arg.data.target).combogrid('clear').combogrid('grid').datagrid('uncheckAll');
                    }
                    g.combogrid(opts);
                    gopts.toolbar = [
                        {
                            iconCls:{cls:'btn btn-sm btn-primary',text:'浏览'},
                            handler:function(arg,gridId="#"+gopts.id){Objs.comboFile.change(gridId,arg);},
                        },{
                            iconCls:{cls:'btn btn-sm btn-info',text:'上传'},
                            handler:function(arg,gridId="#"+gopts.id){Objs.comboFile.upload(gridId,arg);},
                        },{
                            iconCls:{cls:'btn btn-sm btn-default',text:'清空'},
                            handler:function(arg,gridId="#"+gopts.id){Objs.comboFile.clear(gridId,arg);},
                        },{
                            iconCls:{cls:'btn btn-sm btn-hope',text:'选择'},
                            handler:function(arg,gridId="#"+gopts.id){Objs.comboFile.choose(gridId,arg);},
                        }
                    ];
                    gopts.frozenColumns = [[
                        {field:'index',title:'index',checkbox:true},
                        {field:'fileName',title:'文件名称',width:150,
                            formatter:function(value,row,index){
                                if (row.filePath){
                                    return '<a target="_blank" href="'+row.filePath+'">'+value+'</a>';
                                }else{
                                    return value;
                                }
                            }
                        },
                    ]];
                    gopts.columns = [[
                        {field:'fileSize',title:'文件大小',width:80,
                            formatter:function(value,row,index){
                                if (value > 0){
                                    var i = 0,unitArr = new Array('bytes','KB','MB','GB');
                                    while(value > 1023){
                                        value = Math.floor((value/1024)*100)/100;
                                        i++;
                                    }
                                    value += unitArr[i];
                                }else{
                                    value = '';
                                }
                                return value;
                            }
                        },
                        {field:'fileType',title:'文件类型',width:80},
                    ]];
                    if (opts.progress){
                        gopts.columns[0].push({field:'progress',title:'上传进度',width:130,align:'center',
                            formatter:function(value,row,index){
                                return '<div class="zpgbar" data-options="height:18,value:'+value+'"></div>';
                            }
                        });
                    }
                    gopts.columns[0].push({field:'fileStatus',title:'上传状态',width:80,align:'center',
                        formatter:function(value,row,index){
                            switch(value){
                                case 1:
                                    return '上传成功';
                                    break;
                                case -1:
                                    return '上传失败';
                                    break;
                                default:
                                    return '等待上传';
                            }
                        }
                    });
                    gopts.columns[0].push({field:'fileOperate',title:'操作',width:80,
                        formatter:function(value,row,index){
                            var _html = '';
                            _html += '<a href="javascript:;" class="btn btn-xs btn-danger" onclick="$.comboFile.delete(\'#'+opts.id+'\',this)">删除</a>';
                            if (row.fileStatus === 0 && opts.progress){
                                _html += '<a href="javascript:;" class="btn btn-xs btn-hope" onclick="$.comboFile.upload(\'#'+opts.id+'\',this)">上传</a>';
                            }
                            return _html;
                        }
                    });
                    // gopts.checkOnSelect = false;
                    // gopts.selectOnCheck = false;
                    gopts.onClickRow =function(){return false;};
                    gopts.onSelect =function(){return false;};
                    gopts.onSelectAll =function(){return false;};
                    gopts.onDblClickRow =function(){return false;};
                    gopts.onClickCell =function(){return false;};
                    gopts.onDblClickCell =function(){return false;};
                    gopts.onUnselect =function(){return false;};
                    gopts.onUnselectAll =function(){return false;};
                    grid.datagrid(gopts);
                    g.combogrid('textbox').attr('readonly', 'readonly');
                });
            },
            change:function(gridId,target){
                var g = $(gridId),
                    opts = g.combogrid('options'),
                    grid = g.combogrid('grid'),
                    gopts = grid.datagrid('options');
                    tt = g.attr('t'),
                    t = 't'+new Date().getTime();

                if ($('.'+tt).length === 0){
                    g.attr('t',t);
                    var f = $('<div></div>').appendTo('body').hide().addClass(t);
                }else{
                    var f = $('div.'+tt).empty();
                }
                var finp = $('<input type="file">').appendTo(f);
                if (opts.multiple){
                    finp.attr('multiple', 'multiple');
                }
                if (opts.accept){
                    finp.attr('accept', opts.accept);
                }
                finp.click();

                finp[0].onchange =function(gridId){
                    var files = $(this).prop('files'),
                        rows = grid.datagrid('getData')['rows'],
                        cl = rows.map(function(item){return item.fileName;});
                    for (var i = 0; i < files.length; i++){
                        if (cl.indexOf(files[i].name) > -1){
                            continue;
                        }
                        if (opts.limit){
                            vfileSize = Objs.utils.fileSize(opts.limit[0],opts.limit[1]);
                            if (vfileSize.formula === 0){
                                Objs.msger.show('warning',vfileSize.message);
                                continue;
                            }
                            if (this.files[0].size > parseFloat(opts.limit[0]) * vfileSize.formula){
                                Objs.msger.show('warning','上传文件不能大于'+opts.limit[0]+opts.limit[1]);
                                continue;
                            };
                        }
                        grid.datagrid('insertRow',{
                            row:{
                                fileName:files[i].name,
                                fileSize:files[i].size,
                                fileType:files[i].type,
                                filePath:'',
                                progress:0,
                                fileStatus:0,
                                fileOperate:0,
                                file:files[i],
                            }
                        });
                    }
                    if (opts.progress){
                        g.combogrid('panel').find('td[field=progress] .zpgbar').each(function(index, el){
                            if ($(el).is(":empty")){
                                $(el).progressbar();
                            }
                        });
                    }
                    $(this).remove();
                }
            },
            upload:function(gridId,target){
                var g = $(gridId),
                    reg=/\\|\/|\?|\？|\*|\"|\“|\”|\'|\‘|\’|\<|\>|\{|\}|\[|\]|\【|\】|\：|\:|\、|\^|\$|\!|\~|\`|\|/g,
                    opts = g.combogrid('options'),
                    grid = g.combogrid('grid'),
                    gopts = grid.datagrid('options'),
                    panel = g.combogrid('panel'),
                    rows = {},trows = {},
                    tr = $(target).closest('tr.datagrid-row');
                    opts.name = g.attr('textboxname').replace(reg,"");
                if (tr.length===0){
                    trows = grid.datagrid('getChecked');
                }else{
                    var index = parseInt(tr.attr('datagrid-row-index')),
                        allrows = grid.datagrid('getRows');
                    trows[index] = allrows[index];
                }
                // 过滤不存在的文件，必须是待上传的文件
                for (var i in trows){
                    if (trows[i].file !== undefined && trows[i].fileStatus === 0){
                        rows[i] = trows[i];
                    }
                }
                if (Objs.utils.isEmptyObj(rows)){
                    Objs.msger.show('warning','请选择待上传的行数据');
                    return false;
                }

                var xhrOnProgress =function(callobj){
                    xhrOnProgress.element = callobj.element; //绑定监听
                    xhrOnProgress.onprogress = callobj.callback; //绑定监听
                    //使用闭包实现监听绑
                    return function(){
                        //通过$.ajaxSettings.xhr();获得XMLHttpRequest对象
                        var xhr = $.ajaxSettings.xhr();
                        //判断监听函数是否为函数
                        if (typeof xhrOnProgress.onprogress !== 'function') return xhr;
                        //如果有监听函数并且xhr对象支持绑定时就把监听函数绑定上去
                        if (xhrOnProgress.onprogress && xhr.upload){
                            xhr.upload.onprogress = xhrOnProgress.onprogress;
                            xhr.upload.element = xhrOnProgress.element;
                        }
                        return xhr;
                    }
                }
                var params = {
                    url:Objs.utils.urlSetParams(opts.url,{m:'u'}),
                    type:"post",
                    dataType:"json",
                    cache:false,//上传文件无需缓存
                    processData:false,//用于对data参数进行序列化处理 这里必须false
                    contentType:false,//必须
                };
                if (tr.length===0){
                    panel.find('.datagrid-toolbar a.btn').each(function(index, el){
                        $(el).attr("disabled","disabled").addClass("disabled");
                        el.onclick = eval(function(){});
                    });
                }else{
                    $(target).attr("disabled","disabled").addClass("disabled");
                    target.onclick = eval(function(){});
                }
                if (opts.progress){
                    var n=0,m=0;
                    for (var i in rows){
                        m++;
                        var formData = new FormData(),file = rows[i].file;
                        formData.append(opts.name?opts.name:'file', file);
                        params.data = formData;
                        params.index = i;
                        params.xhr = xhrOnProgress({
                            element:panel.find('tr.datagrid-row[datagrid-row-index='+i+']').find('.zpgbar'),
                            callback:function(e){
                                var progress = Math.floor((e.loaded/e.total)*100);//文件上传百分比
                                if (progress < 100){
                                    this.element.progressbar('setValue', progress);
                                }
                            }
                        });
                        Objs.requestAjax(params,function(res){
                            if (!res instanceof Object){
                                res = eval('(' + res + ')');
                            }
                            var barrow = panel.find('tr.datagrid-row[datagrid-row-index='+this.index+']');
                            grid.datagrid('updateRow',{index:this.index,row:res.fileInfo});
                            barrow.find('.zpgbar').progressbar();
                            grid.datagrid('uncheckAll');
                            g.combogrid('setValues',[])

                            // 所有上传都返回结果了才执行
                            n++;
                            if (n===m && tr.length===0){
                                panel.find('.datagrid-toolbar a.btn').each(function(index, el){
                                    $(el).removeAttr("disabled").removeClass("disabled");
                                    el.onclick = eval(gopts.toolbar[index].handler||function(){});
                                });
                            }
                        });
                    }
                }else{
                    var formData = new FormData(),n=0;
                    for (var i in rows){
                        file = rows[i].file;
                        formData.append(n, file);
                        n++;
                    }
                    params.data = formData;
                    Objs.msger.progress(true);
                    Objs.requestAjax(params,function(res){
                        grid.datagrid('uncheckAll');
                        g.combogrid('setValues',[])
                        if (!res instanceof Object){
                            res = eval('(' + res + ')');
                        }
                        Objs.msger.progress(false);
                        res.message = (res.message !== undefined && res.message !== '')?res.message:'message参数不存在';
                        if (res.status !== undefined){
                            Objs.msger.show($.inArray(res.status, [1,'1',true,'true']) >= 0?'success':'warning',res.message,{
                                onHidden:function(){
                                    if (tr.length===0){
                                        panel.find('.datagrid-toolbar a.btn').each(function(index, el){
                                            $(el).removeAttr("disabled").removeClass("disabled");
                                            el.onclick = eval(gopts.toolbar[index].handler||function(){});
                                        });
                                    }
                                    grid.datagrid('reload',{});
                                }
                            });
                        }
                    });
                }
            },
            clear:function(gridId,target){
                var g = $(gridId),
                    grid = g.combogrid('grid'),
                    rows = grid.datagrid('getRows');
                if (rows.length === 0){
                    Objs.msger.show('warning','已经没有行数据了');
                    return false;
                }
                for (var i = rows.length-1; i > -1; i--){
                    // 只清除待上传的文件行
                    if (rows[i].fileStatus === 0){
                        grid.datagrid('deleteRow',i);
                    }
                }
                Objs.msger.show('info','操作完成');
            },
            delete:function(gridId,target){
                var g = $(gridId),
                    data = {},
                    opts = g.combogrid('options'),
                    grid = g.combogrid('grid'),
                    rows = grid.datagrid('getRows'),
                    tr = $(target).closest('tr.datagrid-row'),
                    index = parseInt(tr.attr('datagrid-row-index'));
                delete rows[index].file;
                // ajax 删除远程服务器的文件
                Objs.msger.progress(true);
                Objs.requestAjax({url:Objs.utils.urlSetParams(opts.url,{m:'d'}),data:rows[index]},function(res){
                    if (!res instanceof Object){
                        res = eval('(' + res + ')');
                    }
                    grid.datagrid('uncheckAll');
                    g.combogrid('setValues',[])
                    Objs.msger.progress(false);
                    res.message = (res.message !== undefined && res.message !== '')?res.message:'message参数不存在';
                    if (res.status !== undefined){
                        Objs.msger.show($.inArray(res.status, [1,'1',true,'true']) >= 0?'success':'warning',res.message);
                        if ($.inArray(res.status, [1,'1',true,'true']) >= 0){
                            grid.datagrid('deleteRow',index);
                        }else{
                            Objs.msger.alert('error',res.message);
                        }
                    }
                });
            },
            choose:function(gridId,target){
                var g = $(gridId),
                    opts = g.combogrid('options'),
                    grid = g.combogrid('grid'),
                    fileTexts = [],fileVals = [];
                trows = grid.datagrid('getChecked');
                if (trows.length == 0 && target!== false){
                    Objs.msger.show('warning','请选择要使用的行数据');
                    return false;
                }
                if (opts.multiple){
                    for(var i in trows){
                        if (trows[i].fileStatus === 1){
                            // fileTexts.push(trows[i].fileName);
                            fileVals.push(trows[i].filePath);
                        }
                    }
                }else{
                    if (trows.length !== 1){
                        Objs.msger.show('warning','请选择一条行数据');
                        return false;
                    }
                    if (trows[0].fileStatus === 1){
                        // fileTexts.push(trows[0].fileName);
                        fileVals.push(trows[0].filePath);
                    }
                }
                g.combogrid('setValues', fileVals);
                // var tbox = g.combogrid('combo');
                // tbox.textbox('setValues',fileVals);
            },
        },
        zTree:{
            check:function(arg){
                var ischk = $(arg).prop('checked'),_li = $(arg).closest('.zTree-node');
                if (ischk) {
                    _li.addClass('selected');
                }else{
                    _li.removeClass('selected active').removeAttr('checked');
                };
            },
            toggle:function(arg){
                var _child = $(arg).closest('li').find('ul');
                if (_child.length > 0) {
                    _child.slideToggle(function() {
                        if ($(this).is(":hidden")) {
                            $(arg).removeClass('fa-folder-open').addClass('fa-folder');
                        }else{
                            $(arg).removeClass('fa-folder').addClass('fa-folder-open');
                        };
                    });
                }
            },
            render:function() {}
        },
        toastr:function(options){
            var $container;
            var listener;
            var toastId = 0;
            var result = {
                clear: clear,
                remove: remove,
                getContainer: getContainer,
                options: options,
                subscribe: subscribe,
                version: '2.1.4',
                notify: notify,
            };

            var previousToast;

            return result;

            ////////////////

            function getContainer(options, create) {
                if (!options) { options = getOptions(); }
                $container = $('#' + options.containerId);
                if ($container.length) {
                    return $container;
                }
                if (create) {
                    $container = createContainer(options);
                }
                return $container;
            }

            function subscribe(callback) {
                listener = callback;
            }

            function clear($toastElement, clearOptions) {
                var options = getOptions();
                if (!$container) { getContainer(options); }
                if (!clearToast($toastElement, options, clearOptions)) {
                    clearContainer(options);
                }
            }

            function remove($toastElement) {
                var options = getOptions();
                if (!$container) { getContainer(options); }
                if ($toastElement && $(':focus', $toastElement).length === 0) {
                    removeToast($toastElement);
                    return;
                }
                if ($container.children().length) {
                    $container.remove();
                }
            }

            // internal functions

            function clearContainer (options) {
                var toastsToClear = $container.children();
                for (var i = toastsToClear.length - 1; i >= 0; i--) {
                    clearToast($(toastsToClear[i]), options);
                }
            }

            function clearToast ($toastElement, options, clearOptions) {
                var force = clearOptions && clearOptions.force ? clearOptions.force : false;
                if ($toastElement && (force || $(':focus', $toastElement).length === 0)) {
                    $toastElement[options.hideMethod]({
                        duration: options.hideDuration,
                        easing: options.hideEasing,
                        complete: function () { removeToast($toastElement); }
                    });
                    return true;
                }
                return false;
            }

            function createContainer(options) {
                $container = $('<div/>')
                    .attr('id', options.containerId)
                    .addClass(options.positionClass);

                $container.appendTo($(options.target));
                return $container;
            }

            function publish(args) {
                if (!listener) { return; }
                listener(args);
            }

            function notify(map) {
                var options = getOptions();
                map.iconClass = options.iconClasses[map.type];
                var iconClass = map.iconClass || options.iconClass;

                if (typeof (map.optionsOverride) !== 'undefined') {
                    options = $.extend(options, map.optionsOverride);
                    iconClass = map.optionsOverride.iconClass || iconClass;
                }

                if (shouldExit(options, map)) { return; }

                toastId++;

                $container = getContainer(options, true);

                var intervalId = null;
                var $toastElement = $('<div/>');
                var $titleElement = $('<div/>');
                var $messageElement = $('<div/>');
                var $progressElement = $('<div/>');
                var $closeElement = $(options.closeHtml);
                var progressBar = {
                    intervalId: null,
                    hideEta: null,
                    maxHideTime: null
                };
                var response = {
                    toastId: toastId,
                    state: 'visible',
                    startTime: new Date(),
                    options: options,
                    map: map
                };

                personalizeToast();

                displayToast();

                handleEvents();

                publish(response);

                if (options.debug && console) {
                    console.log(response);
                }

                return $toastElement;

                function escapeHtml(source) {
                    if (source == null) {
                        source = '';
                    }

                    return source
                        .replace(/&/g, '&amp;')
                        .replace(/"/g, '&quot;')
                        .replace(/'/g, '&#39;')
                        .replace(/</g, '&lt;')
                        .replace(/>/g, '&gt;');
                }

                function personalizeToast() {
                    setIcon();
                    setTitle();
                    setMessage();
                    setCloseButton();
                    setProgressBar();
                    setRTL();
                    setSequence();
                    setAria();
                }

                function setAria() {
                    var ariaValue = '';
                    switch (map.iconClass) {
                        case 'toast-success':
                        case 'toast-info':
                            ariaValue =  'polite';
                            break;
                        default:
                            ariaValue = 'assertive';
                    }
                    $toastElement.attr('aria-live', ariaValue);
                }

                function handleEvents() {
                    if (options.closeOnHover) {
                        $toastElement.hover(stickAround, delayedHideToast);
                    }

                    if (!options.onclick && options.tapToDismiss) {
                        $toastElement.click(hideToast);
                    }

                    if (options.closeButton && $closeElement) {
                        $closeElement.click(function (event) {
                            if (event.stopPropagation) {
                                event.stopPropagation();
                            } else if (event.cancelBubble !== undefined && event.cancelBubble !== true) {
                                event.cancelBubble = true;
                            }

                            if (options.onCloseClick) {
                                options.onCloseClick(event);
                            }

                            hideToast(true);
                        });
                    }

                    if (options.onclick) {
                        $toastElement.click(function (event) {
                            options.onclick(event);
                            hideToast();
                        });
                    }
                }

                function displayToast() {
                    $toastElement.hide();

                    $toastElement[options.showMethod](
                        {duration: options.showDuration, easing: options.showEasing, complete: options.onShown}
                    );

                    if (options.timeOut > 0) {
                        intervalId = setTimeout(hideToast, options.timeOut);
                        progressBar.maxHideTime = parseFloat(options.timeOut);
                        progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
                        if (options.progressBar) {
                            progressBar.intervalId = setInterval(updateProgress, 10);
                        }
                    }
                }

                function setIcon() {
                    if (map.iconClass) {
                        $toastElement.addClass(options.toastClass).addClass(iconClass);
                    }
                }

                function setSequence() {
                    if (options.newestOnTop) {
                        $container.prepend($toastElement);
                    } else {
                        $container.append($toastElement);
                    }
                }

                function setTitle() {
                    if (map.title) {
                        var suffix = map.title;
                        if (options.escapeHtml) {
                            suffix = escapeHtml(map.title);
                        }
                        $titleElement.append(suffix).addClass(options.titleClass);
                        $toastElement.append($titleElement);
                    }
                }

                function setMessage() {
                    if (map.message) {
                        var suffix = map.message;
                        if (options.escapeHtml) {
                            suffix = escapeHtml(map.message);
                        }
                        $messageElement.append(suffix).addClass(options.messageClass);
                        $toastElement.append($messageElement);
                    }
                }

                function setCloseButton() {
                    if (options.closeButton) {
                        $closeElement.addClass(options.closeClass).attr('role', 'button');
                        $toastElement.prepend($closeElement);
                    }
                }

                function setProgressBar() {
                    if (options.progressBar) {
                        $progressElement.addClass(options.progressClass);
                        $toastElement.prepend($progressElement);
                    }
                }

                function setRTL() {
                    if (options.rtl) {
                        $toastElement.addClass('rtl');
                    }
                }

                function shouldExit(options, map) {
                    if (options.preventDuplicates) {
                        if (map.message === previousToast) {
                            return true;
                        } else {
                            previousToast = map.message;
                        }
                    }
                    return false;
                }

                function hideToast(override) {
                    var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod;
                    var duration = override && options.closeDuration !== false ?
                        options.closeDuration : options.hideDuration;
                    var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing;
                    if ($(':focus', $toastElement).length && !override) {
                        return;
                    }
                    clearTimeout(progressBar.intervalId);
                    return $toastElement[method]({
                        duration: duration,
                        easing: easing,
                        complete: function () {
                            removeToast($toastElement);
                            clearTimeout(intervalId);
                            if (options.onHidden && response.state !== 'hidden') {
                                options.onHidden();
                            }
                            response.state = 'hidden';
                            response.endTime = new Date();
                            publish(response);
                        }
                    });
                }

                function delayedHideToast() {
                    if (options.timeOut > 0 || options.extendedTimeOut > 0) {
                        intervalId = setTimeout(hideToast, options.extendedTimeOut);
                        progressBar.maxHideTime = parseFloat(options.extendedTimeOut);
                        progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
                    }
                }

                function stickAround() {
                    clearTimeout(intervalId);
                    progressBar.hideEta = 0;
                    $toastElement.stop(true, true)[options.showMethod](
                        {duration: options.showDuration, easing: options.showEasing}
                    );
                }

                function updateProgress() {
                    var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100;
                    $progressElement.width(percentage + '%');
                }
            }

            function getOptions() {
                return $.extend({}, {
                    tapToDismiss: true,
                    toastClass: 'toast',
                    containerId: 'toast-container',
                    debug: false,

                    showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
                    showDuration: 300,
                    showEasing: 'swing', //swing and linear are built into jQuery
                    onShown: undefined,
                    hideMethod: 'fadeOut',
                    hideDuration: 100,
                    hideEasing: 'linear',
                    onHidden: undefined,
                    closeMethod: false,
                    closeDuration: false,
                    closeEasing: false,
                    closeOnHover: true,

                    extendedTimeOut: 1000,
                    iconClasses: {
                        error: 'toast-error',
                        info: 'toast-info',
                        success: 'toast-success',
                        warning: 'toast-warning'
                    },
                    iconClass: 'toast-info',
                    positionClass: 'toast-top-right',
                    timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky
                    titleClass: 'toast-title',
                    messageClass: 'toast-message',
                    escapeHtml: false,
                    target: 'body',
                    closeHtml: '<button type="button">&times;</button>',
                    closeClass: 'toast-close-button',
                    newestOnTop: false,
                    preventDuplicates: true,
                    progressBar: true,
                    progressClass: 'toast-progress',
                    rtl: false,
                    closeButton:true,
                }, result.options);
            }

            function removeToast($toastElement) {
                if (!$container) { $container = getContainer(); }
                if ($toastElement.is(':visible')) {
                    return;
                }
                $toastElement.remove();
                $toastElement = null;
                if ($container.children().length === 0) {
                    $container.remove();
                    previousToast = undefined;
                }
            }
        },
        comboFuns:{
            openWindow:function(opts,params){
                window.open(opts.url);
            },
            openTab:function(opts,params){
                var _request = Objs.utils.urlRequest(opts.oTab.url);
                if (opts.grid !== undefined) {
                    var rows = Objs.grid.getRows(opts.grid),data = Objs.grid.paramData(rows,opts.grid);
                    if (!data){
                        return false;
                    }
                    for(var i in data){
                        if(data[i] instanceof Array){
                            _request.request[i] = data[i].join(',');
                        }else{
                            _request.request[i] = data[i];
                        }
                    }
                }
                opts.oTab.url = _request.domain+'?'+Objs.utils.urlString(_request.request);
                var str = '';
                for (var i in opts.oTab) {
                    if (typeof opts.oTab[i] === 'boolean') {
                        str += i+":"+opts.oTab[i]+",";
                    }else{
                        str += i+":'"+opts.oTab[i]+"',";
                    }
                }
                Objs.TN.open(str);
            },
            closeTab:function(opts,params){
                if (opts.cTab.question === true){
                    if (params.autoClose === 'on'){
                        Objs.TN.close("ttarget:'"+opts.cTab.ttarget+"'");
                    }
                }else{
                    Objs.TN.close("ttarget:'"+opts.cTab.ttarget+"'");
                }
            },
            refreshTab:function(opts,params) {
                Objs.TN.refresh();
            },
            refreshFullPage:function() {
                parent.location.reload();
            },
            request:function(opts,params){
                if (window.frames.length != parent.frames.length){
                　　  top.location.href = opts.url;
                }else{
                    window.location.href = opts.url;
                }
            },
            openDialog:function(opts,params){
                var _def = {
                    maximized:false,
                    minimized:true,
                };
                if (opts.dialog.content !== undefined){
                    var s = opts.dialog.content,
                        temp = $(opts.dialog.content),
                        bby = 'body',
                        btns = 'buttons',
                        btns_ele = temp.find('[dialog='+btns+']'),
                        bby_ele = temp.find('[dialog='+bby+']');
                    if (s.substr(0,1) == '#' || s.substr(0,1) == '.'){
                        s = s.substr(1);
                    }

                    opts.dialog.buttons = '#'+s+btns;
                    if (btns_ele.length > 0){
                        btns_ele.attr('id', s+btns);
                    }

                    opts.dialog.content = '#'+s+bby;
                    if (bby_ele.length > 0){
                        bby_ele.attr('id', s+bby);
                    }
                    temp = $('#'+s+bby);
                    var close = $(opts.dialog.buttons).find('.dialog-close');
                    if (close.length == 0){
                        $(opts.dialog.buttons).append('<div class="btn btn-default dialog-close" onclick="$.closeDialog(\''+opts.dialog.content+'\')">关闭</div>')
                    }
                    delete opts.dialog.content;
                    delete opts.dialog.buttons;

                    opts.dialog.onBeforeClose = function() {
                        $(this).dialog('restore');
                    }

                    opts = $.extend(true, {}, _def,opts.dialog);

                    if (temp.length > 0){
                        temp.dialog(opts);
                    }
                }else{
                    var id_ele = '#'+opts.dialog.id;chk_ele = $('html>body').find(id_ele);
                    if (chk_ele.length == 0){
                        $('html>body').append('<div id="'+opts.dialog.id+'" style="display:none" class="dialog-box"></div>');
                    }
                    var _request = Objs.utils.urlRequest(opts.dialog.href);
                    if (opts.grid !== undefined) {
                        var rows = Objs.grid.getRows(opts.grid),data = Objs.grid.paramData(rows,opts.grid);
                        if (!data){
                            return false;
                        }
                        for(var i in data){
                            if(data[i] instanceof Array){
                                _request.request[i] = data[i].join(',');
                            }else{
                                _request.request[i] = data[i];
                            }
                        }
                    }
                    _request.request.dialogId = opts.dialog.id;
                    opts.dialog.href = _request.domain+'?'+Objs.utils.urlString(_request.request);

                    opts.dialog.onBeforeClose = function(){
                        $(this).dialog('destroy');
                    }
                    opts.dialog.onClose = function(){
                        $(this).remove();
                    }

                    delete opts.dialog.id;
                    opts = $.extend(true, {}, _def,opts.dialog);

                    $(id_ele).dialog(opts);
                }
            },
            closeDialog:function(opts,params){
                if (opts.dialog.question === true){
                    if (params.autoClose === 'on'){
                        Objs.closeDialog(opts.dialog.id);
                    }
                }else{
                    Objs.closeDialog(opts.dialog.id);
                }
            },
            reloadGrid:function(opts,params){
                if (opts.grid !== undefined && opts.grid.updateRow !== false){
                    var queryParams;
                    if (opts.grid.type == 'datagrid'){
                        var currentOpts = $(opts.grid.id).datagrid('options');
                        queryParams = currentOpts.queryParams;
                        if (opts.queryParams !== undefined) {
                            queryParams = opts.queryParams;
                        }
                        $(opts.grid.id).datagrid('reload',queryParams);
                    }else if(opts.grid.type == 'treegrid'){
                        var currentOpts = $(opts.grid.id).treegrid('options');
                        queryParams = currentOpts.queryParams;
                        if (opts.queryParams !== undefined) {
                            $(opts.grid.id).treegrid('reload',opts.queryParams.id);
                            return false;
                        }else{
                            var select = $(opts.grid.id).treegrid('getSelected'),
                            root = $(opts.grid.id).treegrid('getRoot'),
                            temp;
                            if (select !== null) {
                                temp = $(opts.grid.id).treegrid('getParent',select[currentOpts.idField]);
                                if (temp == null) {
                                    temp = root;
                                }
                            }else{
                                temp = root;
                            }
                            queryParams.id = temp[currentOpts.idField];
                            $(opts.grid.id).treegrid('reload',queryParams);
                            return false;
                        }
                    }else if(opts.grid.type == 'combogrid'){
                        var grid = $(opts.grid.id).combogrid('grid');
                        grid.datagrid('reload',{});
                    }
                }
            },
            doAjax:function(opts,params){
                if (opts.grid !== undefined) {
                    var rows = Objs.grid.getRows(opts.grid),
                        data = Objs.grid.paramData(rows,opts.grid);
                    opts.data = data;
                }
                if (opts.data !== false){
                    if (opts.confirmMsg == undefined){
                        Objs.ajaxCallback(opts);
                    }else{
                        Objs.msger.confirm(opts.confirmMsg,function(r){
                            if (r){
                                Objs.ajaxCallback(opts);
                            }
                        });
                    }
                }
            },
            query:function(opts,params){
                Objs.submitForm(opts.form.id);
            },
            queryClear:function(opts,params){
                Objs.clearForm(opts.form.id);
            },
            openPanel(opts,params){
                var tt = new Date().getTime(),_def = {fit:true,border:false,href:''},
                    _close,_refresh,parentCls = '';
                    _outer = Objs.jQ(opts.id).empty();
                if (opts.panel.parentCls !== undefined) {
                    parentCls = opts.panel.parentCls;
                    var _header = $('<div></div>').addClass('zpanel-header').appendTo(_outer);
                    _close = $('<div></div>').addClass('zpanel-close').html('<i class="fa fa-close"></i>').appendTo(_header);
                    _refresh = $('<div></div>').addClass('zpanel-refresh').html('<i class="fa fa-refresh"></i>').appendTo(_header);
                    _outer.css('paddingBottom', _header.outerHeight()).addClass(opts.panel.parentCls);
                }
                opts = $.extend(true, {},_def,opts.panel);
                var _inner = $('<div></div>').addClass('zpanel').appendTo(_outer).panel(opts).panel('open');
                if (_refresh) {
                    _refresh[0].onclick = function() {
                        _inner.panel('open').panel('refresh');
                    };
                }
                if (_close) {
                    _close[0].onclick = function() {
                        _inner.panel('destroy');
                        if (parentCls !== '') {
                            _outer.removeClass(parentCls);
                        }
                    };
                }
            },
            reloadPanel(opts,params){
                var def = $(opts.panel.id).panel('options');
                if (opts.panel.url !== undefined){
                    def.href = opts.panel.url;
                }
                def.href = Objs.utils.urlSetParams(def.href,params);
                $(opts.panel.id).panel('open').panel('refresh',def.href);
            },
            export:function(opts,params){
                if (opts.grid !== undefined) {
                    var gridOpts = $(opts.grid.id)[opts.grid.type]('options');
                    params = gridOpts.queryParams;
                    params.sort = gridOpts.sortName;
                    params.order = gridOpts.sortOrder;
                }
                var xhr = Objs.createXmlHttpRequest(),_token = $('meta[name="csrf-token"]').attr('content');
                xhr.open('post', opts.url, true);
                xhr.responseType = 'blob';
                xhr.setRequestHeader('Content-Type', 'application/json;charset=utf-8');
                xhr.setRequestHeader('token', _token);
                xhr.setRequestHeader('X-CSRF-TOKEN', _token);
                xhr.send(JSON.stringify(params));
                xhr.onload = function (data){
                    if (this.readyState == 4 && this.status == 200){
                        var _link = document.createElement('a');
                        _link.href = window.URL.createObjectURL(this.response);
                        //设置文件名称
                        _link.download = decodeURI(xhr.getResponseHeader("fileName"));
                        _link.click();
                    }else{
                        Objs.msger.alert('error',xhr.status+':'+xhr.statusText);
                    }
                }
            },
            clearInput:function(opts,params) {
                $(opts.id)[opts.type]('clear');
            },
            import:function(opts,params) {
                $.thumbFile.change(opts.target);
            },
        },
        comboEvn:function(elem){
            if (elem instanceof Object){
                if (!(elem instanceof jQuery)){
                    elem = $(elem);
                }
            }else{
                elem = $(elem);
            }
            if(elem.length === 0){
                console.warn('Not found this jQuery Object');
                return false;
            }
            var opts = Objs.utils.options(elem);
            opts.target = elem;
            Objs.comboFuns[opts.method](opts);
        },
        ajaxCallback:function(opts,params){
            Objs.msger.progress(true);
            Objs.requestAjax({url:opts.url,data:opts.data},function(res){
                if (!res instanceof Object){
                    res = eval('(' + res + ')');
                }
                Objs.msger.progress(false);
                res.message = (res.message !== undefined && res.message !== '')?res.message:'message参数不存在';
                if (res.status !== undefined){
                    Objs.msger.show($.inArray(res.status, [1,'1',true,'true']) >= 0?'success':'warning',res.message);
                    if ($.inArray(res.status, [1,'1',true,'true']) >= 0){
                        Objs.comboCallback(opts,params);
                    }
                }
            });
        },
        comboCallback:function(opts,params) {
            if (typeof opts.callback === 'Function'){
                eval(opts.callback);
                return true;
            }
            if (opts.callback instanceof Object){
                if (opts.callback instanceof Array){
                    for (var i in opts.callback){
                        opts.callback[i].queryParams = params;
                        Objs.comboFuns[opts.callback[i].method](opts.callback[i],params);
                    }
                }else{
                    opts.callback.queryParams = params;
                    Objs.comboFuns[opts.callback.method](opts.callback,params);
                }
            }
        },
        closeDialog:function(dialogId){
            $(dialogId).dialog('close');
        },
        requestAjax:function (param, callback){
            var def = {
                    type:"POST",
                    url:'',
                    data:{},
                    dataType:'json',
                    success:callback||function(){},
                    error:function(httpRequest){
                        Objs.msger.progress(false);
                        Objs.msger.alert('error',httpRequest.status+':'+httpRequest.statusText);
                    }
                },t = Objs.utils.token(param.data);
            param = $.extend(true, {}, def, param);
            var adds = {
                token:t.tk,
                numberStr:t.n,
                randomStr:t.rc,
                'X-CSRF-TOKEN':$('meta[name="csrf-token"]').attr('content'),
                'token':$('meta[name="csrf-token"]').attr('content'),
            };
            param.data._token = $('meta[name="csrf-token"]').attr('content');
            if (param.headers) {
                $.extend(true, param.headers, adds);
            }else{
                param.headers = adds;
            }
            $.ajax(param);
        },
        submitForm:function(elem,progress){
            // 参数可以是 this $(this) #id $('#id')
            var formDom,_thisDom,elemOpts = {};
            if (!(elem instanceof jQuery)){
                if ($(elem).length == 1 && $(elem)[0].tagName !== 'FORM'){
                    formDom = $(elem).parents('form');
                    _thisDom = $(elem);
                    elemOpts = Objs.utils.options(_thisDom);
                }else{
                    formDom = $(elem);
                }
            }else{
                if (elem.length == 1 && elem[0].tagName !== 'FORM'){
                    formDom = elem.parents('form');
                    _thisDom = elem;
                    elemOpts = Objs.utils.options(_thisDom);
                }else{
                    formDom = elem;
                }
            }
            if (_thisDom.length > 0 && formDom.length === 0){
                formDom = $(elemOpts.form.id);
            }
            if (formDom.length !== 1){
                console.warn('form in not found');
                return false;
            }
            var def = {form:{url:'',iframe:false,novalidate:false,ajax:true}}
                formOpts = Objs.utils.options(formDom),
                opts = $.extend(true,{}, def, formOpts, elemOpts);
            if (progress !== false){
                Objs.msger.progress(true);
            }
            formDom.form('submit',{
                url:opts.form.url,
                iframe:opts.form.iframe,
                novalidate:opts.form.novalidate,
                ajax:opts.form.ajax,
                onSubmit:function(param){
                    if (opts.form.url == ''){
                        Objs.msger.progress(false);
                        var params = decodeURI($(this).serialize()),
                        _request = Objs.utils.urlRequest('?'+params,false);
                        params = _request.request;
                        Objs.comboCallback(opts,params);
                        return false;
                    }
                    var isValid = $(this).form('validate');
                    if (!isValid){
                        Objs.msger.progress(false);
                        Objs.msger.show('warning','表单验证失败');
                    }
                    param._token = $('meta[name="csrf-token"]').attr('content');
                    return isValid;
                },
                success:function(res){
                    _thisDom.removeAttr("disabled").removeClass("disabled");
                    Objs.msger.progress(false);
                    res = eval('(' + res + ')');

                    res.message = (res.message !== undefined && res.message != '')?res.message:'message参数不存在';
                    if (res.status !== undefined && $.inArray(res.status, [1,'1',true,'true']) >= 0){
                        Objs.msger.show('success',res.message,500,{
                            onHidden:function(){
                                Objs.comboCallback(opts,res.data);
                                _thisDom.removeAttr("disabled").removeClass("disabled");
                            }
                        });
                    } else {
                        Objs.msger.show('warning',res.message,1200,{
                            onHidden:function(){
                                _thisDom.removeAttr("disabled").removeClass("disabled");
                            }
                        });
                    }
                }
            });
        },
        clearForm:function(elem){
            // 参数只能是 this $(this)   options 里面必须包含 form ID
            if (typeof elem === 'string'){
                console.warn('params can not string');
                return false;
            }

            var _thisDom,elemOpts = {};
            _thisDom = !(elem instanceof jQuery)?$(elem):elem;
            if (_thisDom.length !== 1){
                console.warn('element in not found');
                return false;
            }

            var def = {form:{url:'',iframe:false,novalidate:false,ajax:true}}
                elemOpts = Objs.utils.options(_thisDom),
                opts = $.extend(true, {}, def, elemOpts);
            if (elemOpts.form.id === undefined || $(elemOpts.form.id).length !== 1){
                console.warn('form in not found');
                return false;
            }
            $(elemOpts.form.id).form('clear');
            Objs.comboCallback(opts,{});
        },
        utils:{
            urlRequest:function(arg,ec){
                var req = {},dn = '';
                if (typeof arg == 'undefined'){
                    arg = window.location.href;
                    dn = window.location.search;
                    dn = arg.replace("",dn);
                }
                if (arg.indexOf("?") != -1){
                    var str = arg.substr(arg.indexOf("?") + 1);
                    dn = arg.substr(0, arg.indexOf("?"));
                    strs = str.split("&");
                    for(var i = 0; i < strs.length; i ++){
                        var k = strs[i].split("=")[0],v = strs[i].split("=")[1];
                        if (k.indexOf("[]") != -1){
                            nk = k.replace("[]","");
                            if (req[nk] == undefined){
                                req[nk] = [];
                            };
                            req[nk].push(ec!==false?encodeURI(v):v);
                        }else{
                            req[k] = ec!==false?encodeURI(v):v;
                        }
                    }
                }else{
                    dn = arg;
                }
                return {domain:dn,request:req};
            },
            urlString:function(arg){
                var _result = [];
                for (var key in arg){
                    var value = arg[key];
                    if (value instanceof Array){
                        for (var i = 0; i < value.length; i++){
                            _result.push(key+'[]='+value[i]);
                        }
                    }else{
                        _result.push(key+'='+value);
                    }
                }
                return _result.length?_result.join('&'):'';
            },
            urlSetParams:function(url,vals){
                var request = Objs.utils.urlRequest(url,false),
                    _domain = request.domain,
                    _request = request.request;
                _request = $.extend(true, {}, _request, vals);
                return _domain+'?'+Objs.utils.urlString(_request);
            },
            zTrim:function (str){
                return str===undefined?'':str.replace(/^\s+|\s+$/gm,'');
            },
            isEmptyObj:function(obj,col){
                if (obj !== null && obj !== false && obj !== undefined && typeof obj !=='undefined'){
                    if (typeof obj === 'object'){
                        if (col !== undefined && typeof col === 'string'){
                            if (obj[col] !== undefined){
                                obj = obj[col];
                            }else{
                                return false;
                            }
                        }
                        for(var key in obj){
                            return false;
                        }
                    }else{
                        return false;
                    }
                }
                return true;
            },
            options:function(ele){
                var opts={},s = '';
                if (typeof ele === 'object'){
                    s = (typeof(ele.attr) !== 'function'?$(ele):ele).attr("data-options");
                    if (s === undefined){
                        return false;
                    }
                    s = s.replace(/[\n\r]/g,'');
                    s = Objs.utils.zTrim(s);
                }else{
                    s = ele;
                }
                if(s){
                    if(s.substring(0,1)!="{"){
                        s="{"+s+"}";
                    }
                    try{
                        opts=(new Function("return "+s))();
                    }catch(e){
                        console.error('data-options is error');
                        return false;
                    }
                }
                return opts;
            },
            dateFormat:function(date,fmt){
                if (typeof(date) !== 'object'){
                    if (date.toString().length == 10 || date.toString().length == 9) {
                        date *=1000;
                    }else{
                        return '';
                    }
                    if(date.toString().length == 13 || date.toString().length == 12){
                        date = new Date(date);
                    }else{
                        date = new Date().getTime();
                    }
                }
                if (fmt){
                    var ret;
                    var o = {
                        "M+":date.getMonth() + 1, //月份
                        "d+":date.getDate(), //日
                        "h+":date.getHours(), //小时
                        "m+":date.getMinutes(), //分
                        "s+":date.getSeconds(), //秒
                        "q+":Math.floor((date.getMonth() + 3) / 3), //季度
                        "S":date.getMilliseconds() //毫秒
                    };
                    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
                    for (var k in o)
                    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1)?(o[k]):(("00" + o[k]).substr(("" + o[k]).length)));
                    return fmt;
                }else{
                    var y = date.getFullYear();
                    var m = date.getMonth()+1;
                    var d = date.getDate();
                    return y+'-'+(m<10?('0'+m):m)+'-'+(d<10?('0'+d):d);
                }
            },
            fileSize:function(size,unit){
                var msg = '',formula = 1;
                if (!size || isNaN(size) || size == 0){
                    msg = '验证文件大小的值不能为 "' + size + '"';
                    return {formula:0,msg:msg};
                } else if (!unit){
                    msg = '请指定验证文件大小的单位';
                    return {formula:0,msg:msg};
                }
                var index = -1;
                var unitArr = new Array("bytes", "kb", "mb", "gb");
                for (var i = 0; i < unitArr.length; i++){
                    if (unitArr[i] == unit.toLowerCase()){
                        index = i;
                        break;
                    }
                }
                if (index == -1){
                    msg = '请指定正确的验证文件大小的单位：['+unitArr.join(',')+']';
                    return {formula:0,msg:msg};
                }
                // 转换为bytes公式
                while (index > 0){
                    formula = formula * 1024;
                    index--;
                }
                return {formula:formula,message:msg};
            },
            encrypt:function(text,tkey,tiv){
                if (tkey===undefined) {
                    tkey = '123456789054321';
                }
                if (tiv===undefined) {
                    tiv = '123456789012345';
                }
                if (tkey.length !== 16) {
                    tkey = tkey.padStart(16, '.');
                }
                if (tiv.length !== 16) {
                    tiv = tiv.padStart(16, '.');
                }
                var encrypted = '';
                try{
                    var key = CryptoJS.enc.Latin1.parse(tkey); //为了避免补位，直接用16位的秘钥
                    var iv = CryptoJS.enc.Latin1.parse(tiv); //16位初始向量
                    encrypted = CryptoJS.AES.encrypt(text, key, {
                            iv: iv,
                            mode:CryptoJS.mode.CBC,
                            padding:CryptoJS.pad.ZeroPadding
                        });
                }catch(e){
                    console.warn(e.name + ": " + e);
                }
                return encrypted;
            },
            randomChar:function(type,len){
                len = len===undefined?32:len;
                var str="",chars = type=='num'?['0','1','2','3','4','5','6','7','8','9']:['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
                for(var i=0;i<len;i++){
                    var pos = Math.round(Math.random() * (chars.length-1));
                    str+=chars[pos];
                }
                return str;
            },
            token:function(data){
                var n = this.randomChar('num'),rc = this.randomChar();
                if (data instanceof Object) {
                    data = JSON.stringify(this.sortByKey(data));
                }
                return {n:n,rc:rc,tk:this.encrypt(data,rc.substr(n.substr(n.slice(0,1),1),16),rc.replace(rc.substr(n.substr(n.slice(0,1),1),16),''))};
            },
            sortByKey:function(obj) {
                const newkey = Object.keys(obj).sort().reverse();
                var newObj = {};
                for (var i = 0; i < newkey.length; i++) {
                    newObj[newkey[i]] = obj[newkey[i]];
                }
                return newObj;
            }
        },
    };
    // 合并对象到 jQuery
    $.extend({
        TN:{
            close:Objs.TN.close,
            open:Objs.TN.open,
            scrollTo:Objs.TN.scrollTo,
            swatch:Objs.TN.swatch,
        },
        Captcha:Objs.Captcha,
        msger:Objs.msger,
        grid:Objs.grid,
        echarts:Objs.echarts,
        thumbFile:{
            change:Objs.thumbFile.change,
            upload:Objs.thumbFile.upload,
            delete:Objs.thumbFile.delete,
        },
        comboFile:{
            upload:Objs.comboFile.upload,
            delete:Objs.comboFile.delete,
        },
        zTree:Objs.zTree,
        comboFuns:Objs.comboFuns,
        comboEvn:Objs.comboEvn,
        closeDialog:Objs.closeDialog,
        requestAjax:Objs.requestAjax,
        submitForm:Objs.submitForm,
        clearForm:Objs.clearForm,
        utils:Objs.utils,
        zhjui:{
            load:Objs.load,
            loadResize:Objs.loadResize,
        },
    });
    // 执行默认加载函数
    $.zhjui.load();
    $(window).resize(function(){
        $.zhjui.loadResize();
    });
});
